<?php


namespace App\Services;


use App\Models\Config;
use App\Utils\Code;
use Illuminate\Database\Eloquent\Builder;

/**
 * Class ConfigService
 * @property string $value
 * @property array $params
 * @package App\Services
 */
class ConfigService extends BaseService
{
    /**
     * 配置详情
     * @param array $params
     * @param bool $abnormal
     * @param bool $isAdmin
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function keyBy(array $params, $abnormal = true, $isAdmin = false) {
        if (!isset($params['keys']) || !$params['keys']) {
            throw new \Exception('配置键名数据集不能为空', Code::PARAMETER_ERROR);
        }
        if (!$this::$admin && !$isAdmin) {
            $model = Config::where('type', 1);
        } else {
            $model = new Config();
        }
        if (is_array($params['keys'])) {
            $model = $model->whereIn('key', $params['keys'])->get()->keyBy('key');
        } else {
            $model = $model->where('key', $params['keys'])->first();
        }
        if (!$model && $abnormal){
            throw new \Exception('不存在该配置项，请联系开发人员', Code::EMPTY_DATA);
        }
        return $model;
    }

    /**
     * 短信通道配置
     * @param array $params
     * @return Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function updateSms(array $params) {
        if (!isset($params['mode']) || !in_array($params['mode'], [1,2])) {
            throw new \Exception('请设置系统支持的短信通道', Code::PARAMETER_ERROR);
        } elseif (!isset($params['signature']) || !$params['signature']) {
            throw new \Exception('短信签名不能为空', Code::PARAMETER_ERROR);
        } elseif (!isset($params['access_ak']) || !$params['access_ak']) {
            throw new \Exception('通道访问密钥不能为空', Code::PARAMETER_ERROR);
        } elseif (!isset($params['access_sk']) || !$params['access_sk']) {
            throw new \Exception('通道访问密码不能为空', Code::PARAMETER_ERROR);
        } elseif ($params['mode'] == 1 && (!isset($params['appid']) || !$params['appid'])) {
            throw new \Exception('腾讯云短信应用唯一标识不能为空', Code::PARAMETER_ERROR);
        }
        $model = $this->keyBy(['keys' => 'sms'], true, true);
        $model->value = $params['mode'];
        $data = $model->params;
        $data['signature'] = $params['signature'];
        $data['access_ak'] = $params['access_ak'];
        $data['access_sk'] = $params['access_sk'];
        $data['appid'] = isset($params['appid']) && $params['appid'] ? $params['appid'] : '';
        if (isset($params['captcha']) && $params['captcha']) {
            $data['tpl']['captcha'] = $params['captcha'];
        }
        $model->params = $data;
        $model->save();
        return $model;
    }

    /**
     * 微信应用配置
     * @param array $params
     * @param $key
     * @return Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function updateWechat(array $params, $key) {
        if (!isset($params['appid']) || !$params['appid']) {
            throw new \Exception('AppID不能为空', Code::PARAMETER_ERROR);
        } elseif (!isset($params['secret']) || !$params['secret']) {
            throw new \Exception('通信密钥不能为空', Code::PARAMETER_ERROR);
        }
        $model = $this->keyBy(['keys' => 'wechat_'.$key], true, true);
        $model->value = $params['appid'];
        $data = $model->params;
        $data['secret'] = $params['secret'];
        if (key_exists('token', $params)) {
            $data['token'] = $params['token'];
        }
        if (key_exists('encodingAESKey', $params)) {
            $data['encodingAESKey'] = $params['encodingAESKey'];
        }
        $model->params = $data;
        $model->save();
        return $model;
    }

    /**
     * @param array $params
     * @return Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function updatePinduoduo(array $params) {
        if (!isset($params['client_id']) || !$params['client_id']) {
            throw new \Exception('ClientId不能为空', Code::PARAMETER_ERROR);
        } elseif (!isset($params['client_secret']) || !$params['client_secret']) {
            throw new \Exception('ClientSecret不能为空', Code::PARAMETER_ERROR);
        }
        $model = $this->keyBy(['keys' => 'pinduoduo'], true, true);
        $model->value = $params['client_id'];
        $data = $model->params;
        $data['client_secret'] = $params['client_secret'];
        $model->params = $data;
        $model->save();
        return $model;
    }

    /**
     * 批量更新配置项
     * @param $keys
     * @param $values
     * @return mixed
     * @throws \Throwable
     */
    public function updateBatch($keys, $values) {
        if (!$keys || !$values) {
            throw new \Exception('请明确你要更新的配置项', Code::PARAMETER_ERROR);
        }
        $keys = is_array($keys) ? $keys : [$keys];
        $values = is_array($values) ? $values : [$values];
        if (count($keys) != count($values)) {
            throw new \Exception('配置键数据集必须要和配置值数据集一致', Code::PARAMETER_ERROR);
        }
        return \DB::transaction(function () use ($keys, $values) {
            $data = [];
            foreach ($keys as $i => $key) {
                $data[$key] = Config::where('key', $key)->first();
                if (!$data[$key]) {
                    throw new \Exception('没有找到你要更新的配置项', Code::EMPTY_DATA);
                }
                $data[$key]->value = in_array($key, ['sub_account']) ? (float)$values[$i] : $values[$i];
                $data[$key]->save();
            }
            return $data;
        });
    }

    /**
     * 微信配置
     * @param array $params
     * @return Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function updateWechatPay(array $params) {
        if (!isset($params['mch_id']) || !$params['mch_id']) {
            throw new \Exception('微信商户号你能为空', Code::PARAMETER_ERROR);
        } elseif (!isset($params['mch_sk']) || !$params['mch_sk']) {
            throw new \Exception('商户通信密钥不能为空', Code::PARAMETER_ERROR);
        }
        $model = $this->keyBy(['keys' => 'wechat_pay'], true, true);
        $model->value = $params['mch_id'];
        $data = $model->params;
        $data['mch_sk'] = $params['mch_sk'];
        if (isset($params['client_key_path']) && $params['client_key_path']) {
            $data['client_key_path'] = $params['client_key_path'];
        }
        if (isset($params['client_cert_path']) && $params['client_cert_path']) {
            $data['client_cert_path'] = $params['client_cert_path'];
        }
        if (isset($params['notify_url']) && $params['notify_url']) {
            $data['notify_url'] = $params['notify_url'];
        }
        $model->params = $data;
        $model->save();
        return $model;
    }

    /**
     * 支付宝配置
     * @param array $params
     * @return Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function updateAlipayPay(array $params) {
        if (!isset($params['appid']) || !$params['appid']) {
            throw new \Exception('支付宝AppID不能为空', Code::PARAMETER_ERROR);
        } elseif (!isset($params['mode']) || !in_array($params['mode'], [1,2])) {
            throw new \Exception('请设置正确的接口加签方式', Code::PARAMETER_ERROR);
        } elseif (!isset($params['merchant_private_key']) || !$params['merchant_private_key']) {
            throw new \Exception('商户应用私钥不能为空', Code::PARAMETER_ERROR);
        } elseif ($params['mode'] == 2 && (!isset($params['alipay_cert_path']) || !$params['alipay_cert_path'])) {
            throw new \Exception('支付宝公钥证书文件路径不能为空', Code::PARAMETER_ERROR);
        } elseif ($params['mode'] == 2 && (!isset($params['alipay_root_cert_path']) || !$params['alipay_root_cert_path'])) {
            throw new \Exception('支付宝根证书文件路径不能为空', Code::PARAMETER_ERROR);
        } elseif ($params['mode'] == 2 && (!isset($params['merchant_cert_path']) || !$params['merchant_cert_path'])) {
            throw new \Exception('应用公钥证书文件路径不能为空', Code::PARAMETER_ERROR);
        }
        $model = $this->keyBy(['keys' => 'alipay_pay'], true, true);
        $model->value = $params['mode'];
        $data = $model->params;
        $data['appid'] = $params['appid'];
        $data['merchant_private_key'] = $params['merchant_private_key'];
        if (isset($params['alipay_public_key']) && $params['alipay_public_key']) {
            $data['alipay_public_key'] = $params['alipay_public_key'];
        } elseif ($model->value == 1) {
            throw new \Exception('支付宝公钥不能为空', Code::PARAMETER_ERROR);
        }
        if (isset($params['merchant_cert_path']) && $params['merchant_cert_path']) {
            $data['merchant_cert_path'] = $params['merchant_cert_path'];
        }
        if (isset($params['alipay_cert_path']) && $params['alipay_cert_path']) {
            $data['alipay_cert_path'] = $params['alipay_cert_path'];
        }
        if (isset($params['alipay_root_cert_path']) && $params['alipay_root_cert_path']) {
            $data['alipay_root_cert_path'] = $params['alipay_root_cert_path'];
        }
        if (isset($params['encrypt_key']) && $params['encrypt_key']) {
            $data['encrypt_key'] = $params['encrypt_key'];
        }
        if (isset($params['notify_url']) && $params['notify_url']) {
            $data['notify_url'] = $params['notify_url'];
        }
        $model->params = $data;
        $model->save();
        return $model;
    }
}
